﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;

namespace Permission
{
    public class PolicyAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
    {


        // private readonly ICurrentPrincipalAccessor _principalAccessor;
        private readonly AsyncLocal<ClaimsPrincipal> _currentPrincipal = new AsyncLocal<ClaimsPrincipal>();

        /// <summary>
        /// 通过IHttpContextAccessor可以获取HttpContext相关信息，但一定要注册服务
        /// </summary>
        private readonly IHttpContextAccessor _accessor;
        /// <summary>
        /// 用于判断请求是否带有凭据和是否登录
        /// </summary>
        public IAuthenticationSchemeProvider Scheme { get; set; }


        /// <summary>
        ///  构造函数注入
        /// </summary>
        public PolicyAuthorizationHandler(IHttpContextAccessor accessor, IAuthenticationSchemeProvider scheme)
        {
            this._accessor = accessor;
            Scheme = scheme;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            //拿到HttpContext
            var httpContext = _accessor.HttpContext;
            //判读请求是否拥有凭据，即是否登录
            var defaultAuthenticate = await Scheme.GetDefaultAuthenticateSchemeAsync();
            if (defaultAuthenticate == null) context.Fail();//没登录直接授权失败

            var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
            //不为空代表登录成功,为空登录失败
            if (result?.Principal != null)
            {

                if (_accessor.HttpContext.User.IsInRole("admin")) context.Succeed(requirement);//超管-直接授权通过
                                                                                              
                var roles = _accessor.HttpContext.User.Claims.Where(c => c.Type == "role").ToList();
                // ClaimTypes
                if (roles?.Count() == 0) context.Fail();//没有角色，直接授权失败


                // 获取当前请求的地址
                //  string requestUrl = httpContext.Request.Path.Value.ToLower();
                // 从权限表中查找当前用户是否有当前请求地址的权限
                var permission = requirement.PermissionName;//.Permissions.FirstOrDefault(a => a.Url.ToLower() == requestUrl && a.UserId == userId);

                //知道了角色，又知道了当前的权限名

                // 如果没找到，代表没有权限
                if (permission == null)
                {
                    context.Fail();
                }
                // 如果找到，就继续往下执行
                context.Succeed(requirement);
            }
            else
            {
                // 获取不到对应值就返回无权限
                context.Fail();
            }



            // throw new NotImplementedException();
            // 先判断是否认证过
            if (!(context.User?.Identity?.IsAuthenticated ?? false))
            {
                context.Fail();
                await Task.CompletedTask;
            }

            string str = "";
            var role = context.User.FindFirst(c => c.Type == ClaimTypes.Role);
            if (role != null)
            {
                var name = requirement.PermissionName;
                //var roleValue = role.Value;
                //var permissions = RolePermissionCache.GetPermissions(role.Value);
                //if (permissions.Contains(requirement.PermissionName))
                //{
                //    context.Succeed(requirement);
                //}
            }
            //else
            //{
            //    context.Fail();
            //}
            await Task.CompletedTask;
        }

    }
}
